<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>题库模拟系统</title>
    <style>
        .box {
            width: 400px;
            height: 400px;
            position: relative;
            left: 550px;
        }

        .title {
            width: 400px;
            height: 100px;
            border: 1px solid #000;
            padding: 10px;
        }

        .answer {
            width: 400px;
            height: 250px;
            border: 1px solid #000;
            padding: 10px;
        }

        #first,
        #second,
        #three {
            width: 80px;
            height: 40px;
            font-size: 16px;
            text-align: center;
            margin-left: 40px;
            margin-bottom: 0px;
        }
    </style>
</head>

<body>
    <div class="box">
        <div class="title" id="questionArea">题目将显示在这里</div>
        <div class="answer" id="answerArea"></div>
        <button id="first">随机点题</button>
        <button id="second">显示答案</button>
        <button id="three">下一道</button>
    </div>

    <script>
        const questionBank = [
            {
                question: '1. 将json字符串 {"name":"zs"}转为json对象的语法？',
                answer: 'const obj = JSON.parse(\'{"name":"zs"}\');'
            },
            {
                question: "2. this指向有哪些？ 改变this指向的方法有哪些？",
                answer: `事件：this绑定的事件源
                对象的方法中的this：this指向对象本身
                    全局函数或者定时器或者 回调函数 ：window
                    箭头函数中的this：不绑定this，this指向该箭头函数所在作用域中的this
                    改变方法：call/apply/bind`
            },
            {
                question: "3. let和var的区别？let和const的区别？",
                answer: `let vs var：
              1. 预解析：var有let 没有
              2. 块级作用域：let有 var有
              3. 变量名重复：var可以，let不可以
              4. 暂时性死区: let 有 var没有
             let vs const：
             const: 声明即赋值，不能先声明后赋值，let可以
             const：定义的常量不可以被修改，let可以`
            },
            {
                question:"4. 简述for..in循环和for..of循环的区别？",
                answer:`数组： for..in循环（遍历下标）和for..of（遍历的是元素）循环都可以，
   对象:  for..in循环
   set集合：for..of（遍历的是元素）
   map集合：for..of(遍历的是键值对)`
            },
            {
                question:"5. 简述字符串中和正则 相关的api，并简述含义和返回值？",
                answer:`1. str.replace('/sb/g','xx')  返回替换后的字符
   2. str.search('字符串或者字符/正则') ： 返回找到首次出现的下标 ，找不到返回-1
   3. str.match(正则/g):  返回数组类型满足正则规则元素`
            },
            {
                question:"6. 写一个正则，用于匹配任意一个或者多个数字？",
                answer:`/^\d+$/`
            },
            {
                question:"7. 什么是事件对象，写出鼠标事件对象的属性有哪些？区别是什么？",
                answer:`事件对象是浏览器在事件触发时自动创建的‌包含事件相关信息的对象
                e.clientX: 鼠标点击位置距离 视口 的左偏移量
    e.clientY: 鼠标点击位置距离 视口 的上偏移量
    e.pageX: 鼠标点击位置距离 页面 的左偏移量
    e.pageY: 鼠标点击位置距离 页面 的上偏移量
    e.offsetX: 鼠标点击位置距离 触发元素 的左偏移量
    e.offsetY: 鼠标点击位置距离 触发元素 的上偏移量`
            },
            {
                question:"8. 写出键盘事件对象的属性有哪些？",
                answer:`e.keyCode: 具体按下的键码  回车键13   A 65  B 66
    e.ctrlKey: 按下ctrl键的同时按下了其他非功能键 结果是true, 否则是false
    e.altKey: 按下alt键的同时按下了其他非功能键 结果是true, 否则是false
    e.shiftKey: 按下shift键的同时按下了其他非功能键 结果是true, 否则是false`
            },
            {
                question:"9. 什么是事件委托，事件委托的好处是什么？",
                answer:`把原本绑定在子元素上的事件，绑定在父元素上，具体点击的元素可以使用e.target来表示
  1. 利用了事件冒泡，将原本需要绑定在子元素上的事件绑定在父元素上，减少系统性能的损耗
  2. 动态新增的元素也会自动获取到父元素绑定的事件`
            },
            {
                question:"10. 写出鼠标事件类型，键盘事件类型，表单事件类型？",
                answer:`鼠标:click,dbclick,mousedown,mouseup,mousemove,
                mouseover,mouseout,mouseenter,mouseleave,contextmenu
                键盘:keydown,keyup,keypress
                表单:input,change,submit,reset,focus,blur,select`
            },
            {
                question:"11. 事件绑定的方式有哪些？区别是什么？",
                answer:`1.内联事件:直接在html标签中定义事件处理函数
                同一元素重复绑定相同事件时，仅最后一个生效
                2.dom0:不支持多事件监听‌
                3.dom2:支持绑定‌多个事件‌（按绑定顺序依次执行）‌。
可控制事件阶段（捕获/冒泡），通过第三参数 true（捕获）或 false（冒泡）‌`
            },
            {
                question:"12. DOM操作样式时，获取样式的语法有哪些,含义是？",
                answer:`1. ‌element.style（内联样式）
                2. ‌window.getComputedStyle()（计算样式）
                 3. ‌element.currentStyle（IE 专用）
                 4. ‌类名操作（间接获取样式）`
            },
            {
                question:"13. DOM操作属性时，操作属性的语法有哪些？",
                answer:`Element.getAttribute()
Element.getAttributeNames()
Element.setAttribute()
Element.hasAttribute()
Element.hasAttributes()
Element.removeAttribute()`
            },
            {
                question:"14. DOM的创建元素节点，尾部追加，插入，克隆，替换，的语法？",
                answer:`使用createElement()创建元素，
                appendChild()尾部追加，
                insertBefore()插入，
                cloneNode()克隆，
                replaceChild()替换`
            },
            {
                question:"15. 写出数组中能改变原数组的api有哪些？",
                answer:`push(),pop(),unshift(),shift(),splice(),reverse(),sort(),fill()`
            },
            {
                question:"16. 什么样的函数可以改造成箭头函数，怎么改？",
                answer:`可以改造成箭头函数的函数是那些不依赖自己this上下文的函数。
                改造方法是将函数声明改为箭头函数形式，例如：function foo() {}改为const foo = () => {}。`
            },
            {
                question:"17. 基本数据类型和引用数据类型的区别？",
                answer:`基本数据类型‌：存储在栈内存中，包括number、string、boolean、undefined、null、symbol、bigint。
‌引用数据类型‌：存储在堆内存中，包括对象（Object）、数组（Array）、
函数（Function）等。引用数据类型通过引用传递。`
            },
        ];

        let currentIndex = 0;
        const questionArea = document.getElementById('questionArea');
        const answerArea = document.getElementById('answerArea');
        let currentAnswer = "";
        answerArea.style.cssText = `
         white-space: pre-line;
        line-height: 1.5;
        font-size:14px;`;
        answerArea.textContent = questionBank[1].answer;
        showQuestion(0);

        document.getElementById('first').addEventListener('click', function () {
            const randomIndex = Math.floor(Math.random() * questionBank.length);
            currentIndex = randomIndex;
            showQuestion(randomIndex);
            answerArea.textContent = "";
        });

        document.getElementById('second').addEventListener('click', function () {
            answerArea.textContent = currentAnswer;
        });

        document.getElementById('three').addEventListener('click', function () {
            currentIndex = (currentIndex + 1) % questionBank.length;
            showQuestion(currentIndex);
            answerArea.textContent = "";
        });
        function showQuestion(index) {
            questionArea.textContent = questionBank[index].question;
            currentAnswer = questionBank[index].answer;
            answerArea.textContent = "";
        }
    </script>
</body>

</html>